package mn.idax.exchange.otc.service;

import com.alibaba.fastjson.JSON;
import mn.idax.exchange.common.SpringUtils;
import mn.idax.exchange.otc.dto.ChatProtocol;
import mn.idax.exchange.otc.dto.ChatRoomAttributes;
import mn.idax.exchange.otc.dto.OrderUserDto;
import mn.idax.exchange.otc.dto.SysOrderDto;
import mn.idax.exchange.otc.entity.ChatLog;
import mn.idax.exchange.otc.entity.UserInfo;
import mn.idax.exchange.otc.enums.LogTypeEnum;
import mn.idax.exchange.otc.enums.MessageTypeEnum;
import mn.idax.exchange.otc.util.I18nUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.zookeeper.Login;
import org.atmosphere.cpr.AtmosphereResource;
import org.atmosphere.cpr.Broadcaster;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collection;

/**
 * @author shihaiming
 *  redis 订阅消息接收
 */
@Service
public class RedisReceiver {

	private static final Logger logger = LoggerFactory.getLogger(ChatRoomService.class);
	private static final Integer SYS_SENDER_ID = 0;
    private static final String USER_LANGUAGE = "language";

    private final static String CHAT_ROOM_ATTRIBUTES = "chatRoomAttributes";

    @Autowired
    private ChatLogService chatLogService;
    @Autowired
    private FileUrlService fileUrlService;

    /**
     * 这里是收到redis通道的消息之后执行的方法
     * @param message
     */
    public void receiveMessage(String message) {
        logger.info("----receiveMessageFromRedisNew:" + message);

        ChatProtocol chatProtocol = JSON.parseObject(message, ChatProtocol.class);

        //如果是用户发送的消息，直接发送出去
        if (chatProtocol.isSaved()) {
            if (chatProtocol.getLogType().equals(LogTypeEnum.system)){
                broadcastSystemMessage(chatProtocol);
            } else {
                broadcastMessage(chatProtocol);
            }
            return;
        }

    	SysOrderDto sysOrderDto = JSON.parseObject(message, SysOrderDto.class);
    	if ((sysOrderDto != null && StringUtils.isEmpty(sysOrderDto.getOrderNum())) || StringUtils.isNotEmpty(sysOrderDto.getOrderId())){
    	    sysOrderDto.setOrderNum(sysOrderDto.getOrderId());
        }
        if (sysOrderDto == null || StringUtils.isEmpty(sysOrderDto.getOrderNum())) {
            logger.warn("----receive message from redis, but orderId not found----");
            return;
        }
        //消息内容不为空时再发送
        if (StringUtils.isEmpty(sysOrderDto.getMessage())) {
            logger.info("----receive message from redis, but message is null----");
            return;
        }

        chatProtocol = new ChatProtocol();
        chatProtocol.setOrderId(sysOrderDto.getOrderNum());
        chatProtocol.setMsgType(MessageTypeEnum.text);
        chatProtocol.setMessage(sysOrderDto.getMessage());

        if(SYS_SENDER_ID.equals(sysOrderDto.getSenderId())) {
        	 chatProtocol.setSenderId(SYS_SENDER_ID);
             chatProtocol.setLogType(LogTypeEnum.system);
        } else {
        	//非系统用户发送的消息，需要判断发送人是买家还是卖家
        	OrderUserDto orderUserDto = chatLogService.getUserByOrderId(sysOrderDto.getOrderNum());
        	chatProtocol.setSenderId(sysOrderDto.getSenderId());

            UserInfo userInfo = SpringUtils.getBean(ChatLogService.class).getUserInfoByOrderIdAndUserId(chatProtocol.getOrderId(), chatProtocol.getSenderId());
            if (userInfo == null) {
                userInfo = SpringUtils.getBean(ChatLogService.class).getUserInfoById(chatProtocol.getSenderId());
                if (userInfo == null) {
                    logger.warn("----user info not found, senderId:{}, chatProtocol{}----", chatProtocol.getSenderId(), JSON.toJSONString(chatProtocol));
                    return;
                } else {
                    logger.info("----user is staff, staff id:{}, chatProtocol{}----", chatProtocol.getSenderId(), JSON.toJSONString(chatProtocol));
                    return;
                }
            }

            if(orderUserDto.getBuyer().equals(sysOrderDto.getSenderId())) {
                 chatProtocol.setLogType(LogTypeEnum.buyerSys);
            } else if(orderUserDto.getSeller().equals(sysOrderDto.getSenderId())) {
                 chatProtocol.setLogType(LogTypeEnum.sellerSys);
            } else {
            	 logger.info("----receive message from redis, but SenderId not found----");
                 return;
            }

            ChatProtocol.addExtraInfo(chatProtocol, userInfo, chatProtocol.getLogType());
        }

//        if (this.chatRedisService.verifyReplaceMessage(sysOrderDto.getMessageId())) {
//            broadcastMessage(chatProtocol);
//            logger.info("----sendOrderStatusChangeMessageToClient don't save:{}----", JSON.toJSONString(chatProtocol));
//            return;
//        }

        /**save chatLog to mongo**/
        if (saveChatLogToMongo(chatProtocol) != null) {
            /**get broadcaster by chatRoom(orderId)**/
            chatProtocol.setSaved(true);
            broadcastMessage(chatProtocol);
            logger.info("----sendOrderStatusChangeMessageToClient do save:{}----", JSON.toJSONString(chatProtocol));
        }
    }

    private void broadcastMessage(ChatProtocol chatProtocol){
        Broadcaster broadcaster = ChatRoomService.broadcasterFactory.lookup(chatProtocol.getOrderId(),true);
        if (broadcaster == null) {
            logger.info("----receive message from redis, but broadcaster not found----");
            return;
        }

        /**check current connect**/
        Collection<AtmosphereResource> resourceCollection = broadcaster.getAtmosphereResources();
        if (resourceCollection.isEmpty()) {
            logger.info("----receive message from redis, but broadcaster not found----");
        } else {
            /**broadcast message **/
            //客服是静态头像
            if (!chatProtocol.getLogType().equals(LogTypeEnum.staff)){
                chatProtocol.setUserLogo(fileUrlService.dealFileUrlAddress(chatProtocol.getUserLogo()));
            }
            broadcaster.broadcast(chatProtocol);
            logger.info("----broadcastMessage broadcast finish {}:" + JSON.toJSONString(chatProtocol));
        }
    }

    private void broadcastSystemMessage(ChatProtocol chatProtocol){
        Broadcaster broadcaster = ChatRoomService.broadcasterFactory.lookup(chatProtocol.getOrderId(),true);
        if (broadcaster == null) {
            logger.info("----systemMessageBroadcaster is null----");
            return;
        }

        /**check current connect**/
        Collection<AtmosphereResource> resourceCollection = broadcaster.getAtmosphereResources();
        if (resourceCollection.isEmpty()) {
            logger.info("----systemMessageResource from redis, but resource not found----");
        } else {
            /**broadcast message **/
            String lang = null;

            String code = chatProtocol.getMessage();
            for (AtmosphereResource atmosphereResource : resourceCollection) {
                ChatProtocol atmpChatProtocol = new ChatProtocol();
                BeanUtils.copyProperties(chatProtocol,atmpChatProtocol);
                atmpChatProtocol.setUserLogo(fileUrlService.dealFileUrlAddress(atmpChatProtocol.getUserLogo()));
                ChatRoomAttributes attribute = (ChatRoomAttributes) atmosphereResource.getRequest().getSession(false).getAttribute(CHAT_ROOM_ATTRIBUTES);
                lang = attribute.getLanguage();
//                lang = atmosphereResource.getRequest().getSession(false).getAttribute(USER_LANGUAGE).toString();
                atmpChatProtocol.setMessage(I18nUtil.getMessage(code , lang, chatProtocol.getDynamicParam()));
                broadcaster.broadcast(atmpChatProtocol,atmosphereResource);
                logger.info("systemMessage chatProtocol is {}",JSON.toJSONString(atmpChatProtocol));
                logger.info("systemMessageAttribute data {}",JSON.toJSONString(attribute));
            }

        }
    }

    /**
     * saveChatLogToMongo
     *
     * @param chatProtocol
     * @return
     */
    private ChatLog saveChatLogToMongo(ChatProtocol chatProtocol) {
        try {
            if (chatProtocol != null) {
                ChatLog chatLog = new ChatLog();
                BeanUtils.copyProperties(chatProtocol, chatLog);
                logger.info("::::SaveChatLog::RedisReceiver", JSON.toJSONString(chatLog));
                return chatLogService.insert(chatLog);
            }
        } catch (Exception e) {
            logger.error("----save chatLog to mongo error----", e);
        }
        return null;
    }

}